package cn.szzsi._web;

import cn.szzsi._Config;
import cn.szzsi.common.cfg.AlipayConfig;
import cn.szzsi.common.exception.BusinessException;
import cn.szzsi.service.*;
import cn.szzsi.common.bean.SystemConfig.StoreFreezeTime;
import cn.szzsi.common.bean.TenpayConfig;
import cn.szzsi.common.bean.WeixinConfig;
import cn.szzsi.common.bean.dto.AjaxResult;
import cn.szzsi.common.bean.dto.PayAttach;
import cn.szzsi.common.kit.*;
import cn.szzsi.common.model.*;
import cn.szzsi.common.model.Deposit.DepositType;
import cn.szzsi.common.model.OrderLog.OrderLogType;
import cn.szzsi.common.model.Payment.PaymentStatus;
import cn.szzsi.common.model.Payment.PaymentType;
import com.jfinal.aop.Before;
import com.jfinal.aop.Clear;
import com.jfinal.kit.HashKit;
import com.jfinal.kit.HttpKit;
import com.jfinal.kit.JsonKit;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.jfinal.weixin.sdk.api.*;
import com.jfinal.weixin.sdk.kit.IpKit;
import com.jfinal.weixin.sdk.kit.PaymentKit;
import com.jfinal.weixin.sdk.utils.JsonUtils;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.xpath.operations.Or;
import org.json.JSONObject;

import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;


/**
 * 前台类 - 支付处理
 *
 */
public class PaymentController extends BaseWebController<Payment> {

    // 支付结果（成功、失败）
    public enum PaymentResult {
        success, failure
    }

    private PaymentType paymentType;// 支付类型
    private BigDecimal amountPayable;// 应付金额
    private BigDecimal paymentFee;// 支付手续费
    private PaymentResult paymentResult;// 支付结果
    private PaymentConfig paymentConfig;// 支付方式
    private Orders order;// 订单
    private OrdersPlateform orderPlateform;
    private String uid;//商户id,也是用户的店铺id
    private String shopId;//店铺id
    private AjaxResult ajax = new AjaxResult();//微信支付返回状态
    //商户相关资料
    private String wechat_mini_appid=_Config.p.get("wechat_mini_appid");
    //private String wechat_mini_secret= _Config.p.get("wechat_mini_secret");//小程序secret
    private String appid=_Config.p.get("wechat_appid");;//微信公众appid
    private String secret=_Config.p.get("wechat_secret");//应用密钥
    private String partner=_Config.p.get("weichat_bargainorId");//商户号
    private String key=_Config.p.get("weichat_key");//支付秘钥
    private String notify_url = _Config.p.get("mall_web.url")+"/b/payment/wxNotice";//回调接口

    // 支付确认
    public void confirm() {
        Member member=getLoginMember();
        String orderPlateFormId=getPara("ordersPlateform.id");//平台生成的订单id
        if(StrKit.isBlank(orderPlateFormId)){
            addActionError("订单信息错误！");
            return;
        }else{
            orderPlateform =OrdersPlateform.dao.findById(orderPlateFormId);
            if(orderPlateform==null){
                addActionError("订单不存在！");
                return;
            }
            paymentConfig=orderPlateform.getPaymentConfig();
            if (orderPlateform.getPaymentStatus()==2) {//已支付
                addActionError("订单付款状态错误！");
                return;
            }
            amountPayable = orderPlateform.getTotalAmount();
        }
        paymentFee = orderPlateform.getPaymentFee();
        amountPayable = orderPlateform.getTotalAmount().subtract(paymentFee).subtract(orderPlateform.getPaidAmount());
        if(paymentConfig.getPaymentConfigTypeValue() == PaymentConfig.PaymentConfigType.weixin){//微信支付
            WeixinConfig weixinConfig=new WeixinConfig();
            weixinConfig.setAppid(appid);
            weixinConfig.setSecret(secret);
            ApiConfigKit.setThreadLocalApiConfig(getApiConfig(weixinConfig));

            JsTicket jsApiTicket = JsTicketApi.getTicket(JsTicketApi.JsApiType.jsapi);
            String jsapi_ticket = jsApiTicket.getTicket();
            String nonce_str = create_nonce_str();
            // 注意 URL 一定要动态获取，不能 hardcode.
            String url=""+ _Config.p.get("mall_web.url")+"" +getRequest().getServletPath();
            String qs = getRequest().getQueryString(); // 参数
            if (qs != null) {
                url = url + "?" + (getRequest().getQueryString());
            }
            String timestamp = create_timestamp();
            // 这里参数的顺序要按照 key 值 ASCII 码升序排序
            //注意这里参数名必须全部小写，且必须有序
            String str = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str + "&timestamp=" + timestamp + "&url=" + url;
            String signature = HashKit.sha1(str);
            setAttr("appId", ApiConfigKit.getApiConfig().getAppId());
            setAttr("nonceStr", nonce_str);
            setAttr("timestamp", timestamp);
            setAttr("url", url);
            setAttr("signature", signature);
            setAttr("base", getRequest().getContextPath());
            setAttr("jsapi_ticket", jsapi_ticket);
            setAttr("openId",member.getOpenid());

        }

        setAttr("orderPlateform", orderPlateform);
        setAttr("paymentType", paymentType);
        setAttr("amountPayable", amountPayable);
        setAttr("paymentFee", paymentFee);
        setAttr("paymentConfig", paymentConfig);
        ApiConfigKit.removeThreadLocalApiConfig();
        pcTemplatePath("payment_confirm.html");
        //getTemplatePath(uid,"payment_confirm");

    }

    // 支付入口
    @Before(Tx.class)
    public void gateway() {
        String orderPlateFormId=getPara("orderPlateFormId");//平台生成的订单id
        if(StrKit.isBlank(orderPlateFormId)){
            addActionError("订单信息错误！");
            return;
        }else{
            orderPlateform =OrdersPlateform.dao.findById(orderPlateFormId);
            if(orderPlateform==null){
                addActionError("订单不存在！");
                return;
            }
            paymentConfig=orderPlateform.getPaymentConfig();
            if (orderPlateform.getPaymentStatus()==2) {//已支付
                addActionError("订单付款状态错误！");
                return;
            }
            amountPayable = orderPlateform.getTotalAmount();
        }
        final Member loginMember = getLoginMember();
        String pt = getPara("paymentType","");
        if (StrKit.notBlank(pt)){
            paymentType = PaymentType.valueOf(pt);
        }
        if(paymentType == PaymentType.deposit) {//预存款支付
            if (paymentConfig.getPaymentConfigTypeValue() != PaymentConfig.PaymentConfigType.deposit) {
                addActionError("支付方式错误！");
                return;
            }
            if (UserBalance.dao.findByMemberId(loginMember.getId()).getBigDecimal("balance").compareTo(orderPlateform.getTotalAmount().subtract(orderPlateform.getPaidAmount())) < 0) {
                paymentResult = PaymentResult.failure;
                setAttr("paymentResult",paymentResult);
                setAttr("loginMember",loginMember);
                render(CommonUtil.TEMPLATE_PATH+"/platform/web/payment_deposit_result.html");
                return;
            }
        } else if (paymentType == PaymentType.point) {//积分支付
            if (paymentConfig.getPaymentConfigTypeValue() != PaymentConfig.PaymentConfigType.point) {
                addActionError("支付方式错误！");
                return;
            }
            if (new BigDecimal(UserBalance.dao.findByMemberId(loginMember.getId()).getInt("point")).compareTo(orderPlateform.getTotalAmount().subtract(orderPlateform.getPaidAmount())) < 0) {
                paymentResult = PaymentResult.failure;
                setAttr("paymentResult",paymentResult);
                setAttr("loginMember",loginMember);
                render(CommonUtil.TEMPLATE_PATH+"/platform/web/payment_point_result.html");
                return;
            }
        }
        // 实际需要支付给第三方金额  应付金额(不含支付费用)-余额抵扣-积分抵扣金额
        BigDecimal totalAmount = amountPayable.subtract(orderPlateform.getPaidDeposit()).subtract(orderPlateform.getPaidPointAsDeposit());// 总金额
        if (paymentConfig.getPaymentConfigTypeValue() == PaymentConfig.PaymentConfigType.deposit||paymentConfig.getPaymentConfigTypeValue() == PaymentConfig.PaymentConfigType.point) {//积分或者余额支付
            if (totalAmount.compareTo(orderPlateform.getTotalAmount().subtract(orderPlateform.getPaidAmount()).subtract(orderPlateform.getPaidDeposit()).subtract(orderPlateform.getPaidPointAsDeposit())) == 0) {//全额支付
                orderPlateform.set("paymentStatus", Orders.PaymentStatus.paid.ordinal());
                orderPlateform.set("paidAmount",orderPlateform.getPaidAmount().add(totalAmount));
            } else if (totalAmount.compareTo(orderPlateform.getTotalAmount().subtract(orderPlateform.getPaidAmount()).subtract(orderPlateform.getPaidDeposit()).subtract(orderPlateform.getPaidPointAsDeposit())) < 0) {
                orderPlateform.set("paymentStatus", Orders.PaymentStatus.partPayment.ordinal());
                orderPlateform.set("paidAmount",orderPlateform.getPaidAmount().add(totalAmount));
            } else {
                addActionError("交易金额错误！");
                return;
            }
            orderPlateform.update();
            if(paymentConfig.getPaymentConfigTypeValue() == PaymentConfig.PaymentConfigType.deposit){//预存款支付
                UserBalanceService.service.updateBalance(loginMember,totalAmount.multiply(new BigDecimal(-1)));//更新会员余额结果
                UserBalanceDetailService.service.savePaymentInfo(loginMember.getId(),orderPlateform.getTotalAmount(), UserBalanceDetail.BalanceType.memberPayment.ordinal(),loginMember.getShopId(),order.getOrderSn());//支付明细
            }else if(paymentConfig.getPaymentConfigTypeValue() == PaymentConfig.PaymentConfigType.point){//积分支付
                UserBalanceService.service.updatePoint(loginMember,-totalAmount.intValue());//更新会员余额结果,待改进,四舍五入问题
                UserPointDetailService.service.saveInfo(loginMember.getId(),totalAmount.intValue(), UserPointDetail.PointDetailType.memberPayment.ordinal(),"订单支付");//积分明细
            }
            //保存支付信息
            PaymentService.service.savePayment(paymentType.ordinal(),paymentConfig.getName(),totalAmount,orderPlateform.getPaymentFee(),loginMember.getUsername(),PaymentStatus.success.ordinal(),paymentConfig.getId(),order.getId(),SerialNumberUtil.buildPaymentSn(),shopId);
            //会员支付完毕,更新会员等级,放到线程里面跑
            _Config.fixedThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    //执行分销处理
                    try {
                        FenxiaoService.service.fenxiaoHandle(loginMember,orderPlateform);
                    } catch (BusinessException e) {
                        e.printStackTrace();
                    }
                }
            });

            // 订单日志
            PaymentService.service.saveOrderLog(OrderLogType.payment.ordinal(),order,paymentConfig,totalAmount.add(order.getPaidDeposit()).add(order.getPaidDeposit()));
            paymentResult = PaymentResult.success;
            setAttr("paymentResult",paymentResult);
            setAttr("amountPayable",amountPayable);
            setAttr("paymentFee",paymentFee);
            redirect("/b/order/view?id="+orderPlateform.getId());
            return;
        }if(paymentConfig.getPaymentConfigTypeValue() == PaymentConfig.PaymentConfigType.alipay){//支付宝支付
            //PaymentService.service.savePayment(paymentType.ordinal(),paymentConfig.getName(),totalAmount,orderPlateform.getPaymentFee(),loginMember.getUsername(),PaymentStatus.ready.ordinal(),paymentConfig.getId(),order.getId(),SerialNumberUtil.buildPaymentSn(),shopId);//保存支付信息
            //给支付宝接口发送请求参数  //将商户的支付宝合作身份者ID和MD5密钥赋值给支付宝即时到账即参数
            String partner= _Config.p.get("alipay_bargainorId");
            String key= _Config.p.get("alipay_key");
            AlipayConfig alipayConfig=new AlipayConfig();
            alipayConfig.setPartner(partner);
            alipayConfig.setKey(key);
            PrintWriter out= null;
            try {
                getResponse().setContentType("text/html;charset=utf-8");
                out = getResponse().getWriter();
            } catch (IOException e) {
                e.printStackTrace();
            }
            String subject=orderPlateform.getOrderSn();//商品名称(暂时用订单号代替)
            DecimalFormat df = new DecimalFormat("0.00"); //付款金额保留几位小数
            String totalFee=df.format(totalAmount);
            StringBuffer sbHtml = new StringBuffer();
            sbHtml.append("<form id=\"alipayform\" action=\""+ _Config.p.get("mall_web.url")+"/html/alipayapi.jsp?_input_charset= \""+ AlipayConfig.input_charset + "\" method=\"POST\">");
            sbHtml.append("<input type=\"hidden\" name=\"WIDout_trade_no\" value=\"" + orderPlateFormId + "\"/>");//订单编号
            sbHtml.append("<input type=\"hidden\" name=\"WIDsubject\" value=\"" + subject + "\"/>");//商品名称
            sbHtml.append("<input type=\"hidden\" name=\"WIDtotal_fee\" value=\"" + totalFee + "\"/>");//付款金额
            sbHtml.append("<input type=\"hidden\" name=\"WIDbody\" value=\"" + totalFee + "\"/>");//商品描述
            sbHtml.append("<script>document.forms['alipayform'].submit();</script>");
            out.println(sbHtml.toString());
            renderNull();
        }else if((paymentConfig.getPaymentConfigTypeValue() == PaymentConfig.PaymentConfigType.weixin)&&("wechatmini".equals(getPara("type")))){
            System.out.println("----------------------小程序支付开始");
            //PaymentService.service.savePayment(paymentType.ordinal(),paymentConfig.getName(),totalAmount,orderPlateform.getPaymentFee(),loginMember.getUsername(),PaymentStatus.ready.ordinal(),paymentConfig.getId(),orderPlateform.getStr("id"),SerialNumberUtil.buildPaymentSn(),shopId);
            String openId=loginMember.getMiniOPenId();
            // 统一下单文档地址：https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
            Map<String, String> params = new HashMap<String, String>();
            params.put("appid", wechat_mini_appid);//AppID(应用ID)
            params.put("mch_id", partner);//商户号
            params.put("body", "微信商城产品在线交易");
            String out_trade_no=orderPlateform.getId();//商户订单号
            params.put("out_trade_no", out_trade_no);
            int price=((int)(Float.valueOf(totalAmount.toString())*100));
            params.put("total_fee", price+"");
            params.put("attach", JsonKit.toJson(new PayAttach(out_trade_no, 2, 3)));
            String ip = IpKit.getRealIp(getRequest());
            if (StrKit.isBlank(ip)) {
                ip = "127.0.0.1";
            }
            params.put("spbill_create_ip", ip);
            params.put("trade_type", PaymentApi.TradeType.JSAPI.name());
            params.put("nonce_str", System.currentTimeMillis() / 1000 + "");
            params.put("notify_url", notify_url);
            params.put("openid", openId);

            String sign = PaymentKit.createSign(params, key);//支付秘钥
            params.put("sign", sign);
            String xmlResult = PaymentApi.pushOrder(params);

            Map<String, String> result = PaymentKit.xmlToMap(xmlResult);
            String return_code = result.get("return_code");
            String return_msg = result.get("return_msg");
            if (StrKit.isBlank(return_code) || !"SUCCESS".equals(return_code)) {
                ajax.addError(return_msg);
                renderJson(ajax);
                return;
            }
            // 以下字段在return_code 和result_code都为SUCCESS的时候有返回
            String prepay_id = result.get("prepay_id");
            Map<String, String> packageParams = new HashMap<String, String>();
            packageParams.put("appId", wechat_mini_appid);
            packageParams.put("timeStamp", System.currentTimeMillis() / 1000 + "");
            packageParams.put("nonceStr", System.currentTimeMillis() + "");
            packageParams.put("package", "prepay_id=" + prepay_id);
            packageParams.put("signType", "MD5");
            String packageSign = PaymentKit.createSign(packageParams, key);
            packageParams.put("paySign", packageSign);
            packageParams.put("prePayId",prepay_id);
            String jsonStr = JsonUtils.toJson(packageParams);
            System.out.println("jsonStr--------"+jsonStr);
            ajax.success(jsonStr);
            renderJson(ajax);
        }else if (paymentConfig.getPaymentConfigTypeValue() == PaymentConfig.PaymentConfigType.weixin) {//微信支付
            System.out.println("----------------------微信支付开始");
            //PaymentService.service.savePayment(paymentType.ordinal(),paymentConfig.getName(),totalAmount,orderPlateform.getPaymentFee(),loginMember.getUsername(),PaymentStatus.ready.ordinal(),paymentConfig.getId(),orderPlateform.getStr("id"),SerialNumberUtil.buildPaymentSn(),shopId);
            String openId=loginMember.getOpenid();
            Map<String, String> params = new HashMap<String, String>();
            params.put("appid", appid);//AppID(应用ID)
            params.put("mch_id", partner);//商户号
            params.put("body", "微信商城产品在线交易");
            String out_trade_no=orderPlateform.getId();//商户订单号
            params.put("out_trade_no", out_trade_no);
            int price=((int)(Float.valueOf(totalAmount.toString())*100));
            params.put("total_fee", price+"");
            params.put("attach", JsonKit.toJson(new PayAttach(out_trade_no, 2, 3)));
            String ip = IpKit.getRealIp(getRequest());
            if (StrKit.isBlank(ip)) {
                ip = "127.0.0.1";
            }
            params.put("spbill_create_ip", ip);
            params.put("trade_type", PaymentApi.TradeType.JSAPI.name());
            params.put("nonce_str", System.currentTimeMillis() / 1000 + "");
            params.put("notify_url", notify_url);
            params.put("openid", openId);

            String sign = PaymentKit.createSign(params, key);//支付秘钥
            params.put("sign", sign);
            String xmlResult = PaymentApi.pushOrder(params);

            Map<String, String> result = PaymentKit.xmlToMap(xmlResult);
            String return_code = result.get("return_code");
            String return_msg = result.get("return_msg");
            if (StrKit.isBlank(return_code) || !"SUCCESS".equals(return_code)) {
                ajax.addError(return_msg);
                renderJson(ajax);
                return;
            }
            // 以下字段在return_code 和result_code都为SUCCESS的时候有返回
            String prepay_id = result.get("prepay_id");
            Map<String, String> packageParams = new HashMap<String, String>();
            packageParams.put("appId", appid);
            packageParams.put("timeStamp", System.currentTimeMillis() / 1000 + "");
            packageParams.put("nonceStr", System.currentTimeMillis() + "");
            packageParams.put("package", "prepay_id=" + prepay_id);
            packageParams.put("signType", "MD5");
            String packageSign = PaymentKit.createSign(packageParams, key);
            packageParams.put("paySign", packageSign);
            String jsonStr = JsonUtils.toJson(packageParams);
            System.out.println("jsonStr--------"+jsonStr);
            ajax.success(jsonStr);
            renderJson(ajax);
        }

    }

    //支付宝服务器异步通知页面
    @Clear
    public void alipayNotice(){
        System.out.println("-----------------付宝服务器异步通知页面");
        //获取支付宝POST过来反馈信息
        Map<String,String> params = new HashMap<String,String>();
        Map requestParams = getRequest().getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }
        //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
        String out_trade_no = new String(getPara("out_trade_no")); //商户订单号
        String trade_no = new String(getPara("trade_no"));//支付宝交易号
        String total_fee= new String(getPara("total_fee"));//交易金额(实际支付给第三方的金额)
        //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
        PrintWriter out= null;
        try {
            getResponse().setContentType("text/html;charset=utf-8");
            out = getResponse().getWriter();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if(AlipayNotify.verify(params)){//验证成功
            //请在这里加上商户的业务逻辑程序代码
            //Payment payment = Payment.dao.getPaymentByOrderId(out_trade_no);
            final OrdersPlateform ordersPlateform=OrdersPlateform.dao.findById(out_trade_no);//平台订单
            final Member loginMember = Member.dao.findById(ordersPlateform.getMemberId());
            BigDecimal totalAmount = ordersPlateform.getTotalAmount();
            paymentFee = ordersPlateform.getPaymentFee();//支付手续费
            paymentConfig=ordersPlateform.getPaymentConfig();
            if (paymentConfig.getPaymentConfigTypeValue() == PaymentConfig.PaymentConfigType.alipay) {
                ordersPlateform.setPaymentStatus(Orders.PaymentStatus.paid.ordinal());
                ordersPlateform.setPaidAmount(ordersPlateform.getPaidAmount().add(totalAmount));
                ordersPlateform.setTradeNo(trade_no);
                ordersPlateform.update();

                //如果该订单用了余额或者积分支付,则添加余额或者支付明细
                if(ordersPlateform.getPaidDeposit().compareTo(new BigDecimal(0))>0){
                    UserBalanceService.service.updateBalance(loginMember,ordersPlateform.getPaidDeposit().multiply(new BigDecimal(-1)));//更新会员余额结果
                    UserBalanceDetailService.service.savePaymentInfo(loginMember.getId(),ordersPlateform.getTotalAmount(), UserBalanceDetail.BalanceType.memberPayment.ordinal(),loginMember.getShopId(),ordersPlateform.getOrderSn());//支付明细
                }
                if(ordersPlateform.getPaidPoints()>0){
                    UserPointDetailService.service.saveInfo(loginMember.getId(),ordersPlateform.getPaidPoints(), UserPointDetail.PointDetailType.memberPayment.ordinal(),"订单支付(积分抵扣)");//积分明细
                }
                //如果该订单用了余额或者积分支付,则添加余额或者支付明细

                UserBalanceDetailService.service.savePaymentInfo(ordersPlateform.getMemberId(),ordersPlateform.getTotalAmount().subtract(ordersPlateform.getPaidDeposit().subtract(ordersPlateform.getPaidPointAsDeposit())), UserBalanceDetail.BalanceType.memberPayment.ordinal(),"-1",ordersPlateform.getOrderSn());

                //平台订单处理完毕,开始进行商户分单处理-->改变订单状态
                List<Orders> ordersList=Orders.dao.getByParentId(ordersPlateform.getId());
                for (Orders order:ordersList){
                    order.set("paymentStatus", Orders.PaymentStatus.paid.ordinal());
                    order.set("paidAmount",order.getPaidAmount().add(totalAmount));
                    order.set("trade_no",trade_no);
                    order.update();
                    PaymentService.service.saveOrderLog(OrderLogType.payment.ordinal(),order,paymentConfig,order.getTotalAmount());
                }
                //平台订单处理完毕,开始进行商户分单处理-->改变订单状态

            } else {
                addActionError("交易类型错误！");
                return;
            }
            out.print("success");	//请不要修改或删除
            System.out.println("**************************用户支付成功*****************");
            renderNull();
        }else{//验证失败
            System.out.println("*********************fail*********************");
            out.print("fail");
        }
    }

    //支付宝页面跳转同步通知页面
    @Clear
    public void alipayReturn(){
        System.out.println("---------------------支付宝页面跳转同步通知页面");
        //获取支付宝GET过来反馈信息
        Map<String,String> params = new HashMap<String,String>();
        Map requestParams = getRequest().getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }
        //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
        String out_trade_no = new String(getPara("out_trade_no"));//商户订单号(平台)
        String trade_no = new String(getPara("trade_no"));//支付宝交易号
        //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
        //计算得出通知验证结果
        boolean verify_result = AlipayNotify.verify(params);
        PrintWriter out= null;
        try {
            getResponse().setContentType("text/html;charset=utf-8");
            out = getResponse().getWriter();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if(verify_result){//验证成功
            //该页面可做页面美工编辑
            //OrdersPlateform ordersPlateform=OrdersPlateform.dao.findById(out_trade_no);//平台订单
            //order=Orders.dao.getOrderByTransactionId(trade_no);
            redirect("/b/order/list");//跳转到订单详情页
        }else{
            System.out.println("******验证失败");
            //该页面可做页面美工编辑
            out.println("验证失败");
        }
    }

    //微信支付结果请求处理
    @Clear
    public void wxNotice() {
        //获取所有的参数
        StringBuffer sbf=new StringBuffer();
        Enumeration<String> en=getParaNames();
        while (en.hasMoreElements()) {
            Object o= en.nextElement();
            sbf.append(o.toString()+"="+getPara(o.toString()));
        }
        // 支付结果通用通知文档: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7
        String xmlMsg = HttpKit.readIncommingRequestData(getRequest());
        System.out.println("支付通知="+xmlMsg);
        Map<String, String> params = PaymentKit.xmlToMap(xmlMsg);
        String result_code  = params.get("result_code");
        String trade_no= params.get("transaction_id"); // 微信支付订单号
        String out_trade_no= params.get("out_trade_no");// 商户订单号
        PrintWriter out= null;
        try {
            getResponse().setContentType("text/html;charset=utf-8");
            out = getResponse().getWriter();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 注意重复通知的情况，同一订单号可能收到多次通知，请注意一定先判断订单状态
        // 避免已经成功、关闭、退款的订单被再次更新
        final OrdersPlateform ordersPlateform=OrdersPlateform.dao.findById(out_trade_no);//平台订单
        final Member loginMember = Member.dao.findById(ordersPlateform.getMemberId());
        BigDecimal totalAmount = ordersPlateform.getTotalAmount();
        paymentFee = ordersPlateform.getPaymentFee();//支付手续费
        paymentConfig=ordersPlateform.getPaymentConfig();
        if (paymentConfig.getPaymentConfigTypeValue() == PaymentConfig.PaymentConfigType.weixin) {
            if(PaymentKit.verifyNotify(params, key)){
                if (("SUCCESS").equals(result_code)) {
                    //更新订单信息,请在这里加上商户的业务逻辑程序代码
                    ordersPlateform.setPaymentStatus(Orders.PaymentStatus.paid.ordinal());
                    ordersPlateform.setPaidAmount(ordersPlateform.getPaidAmount().add(totalAmount));
                    ordersPlateform.setTradeNo(trade_no);
                    ordersPlateform.update();

                    //如果该订单用了余额或者积分支付,则添加余额或者支付明细
                    if(ordersPlateform.getPaidDeposit().compareTo(new BigDecimal(0))>0){
                        UserBalanceService.service.updateBalance(loginMember,ordersPlateform.getPaidDeposit().multiply(new BigDecimal(-1)));//更新会员余额结果
                        UserBalanceDetailService.service.savePaymentInfo(loginMember.getId(),ordersPlateform.getTotalAmount(), UserBalanceDetail.BalanceType.memberPayment.ordinal(),loginMember.getShopId(),ordersPlateform.getOrderSn());//支付明细
                    }
                    if(ordersPlateform.getPaidPoints()>0){
                        UserPointDetailService.service.saveInfo(loginMember.getId(),ordersPlateform.getPaidPoints(), UserPointDetail.PointDetailType.memberPayment.ordinal(),"订单支付(积分抵扣)");//积分明细
                    }
                    //如果该订单用了余额或者积分支付,则添加余额或者支付明细

                    UserBalanceDetailService.service.savePaymentInfo(ordersPlateform.getMemberId(),ordersPlateform.getTotalAmount().subtract(ordersPlateform.getPaidDeposit().subtract(ordersPlateform.getPaidPointAsDeposit())), UserBalanceDetail.BalanceType.memberPayment.ordinal(),"-1",ordersPlateform.getOrderSn());

                    //平台订单处理完毕,开始进行商户分单处理-->改变订单状态
                    List<Orders> ordersList=Orders.dao.getByParentId(ordersPlateform.getId());
                    for (Orders order:ordersList){
                        order.set("paymentStatus", Orders.PaymentStatus.paid.ordinal());
                        order.set("paidAmount",order.getPaidAmount().add(totalAmount));
                        order.set("trade_no",trade_no);
                        order.update();
                        PaymentService.service.saveOrderLog(OrderLogType.payment.ordinal(),order,paymentConfig,order.getTotalAmount());
                    }

                    //发送通知等
                    Map<String, String> xml = new HashMap<String, String>();
                    xml.put("return_code", "SUCCESS");
                    xml.put("return_msg", "OK");
                    out.print(PaymentKit.toXml(xml));
                    //renderText(PaymentKit.toXml(xml).toString());
                    System.out.println("**********************订单支付成功");
                    renderNull();
                    return;
                }
            }
        }
        System.out.println("**********************微信交易结束结束");
        renderNull();
    }


    public ApiConfig getApiConfig(WeixinConfig weixinConfig) {
        ApiConfig ac = new ApiConfig();
        // 配置微信 API 相关常量
        //ac.setToken(AConfig.p.get("token"));
        ac.setAppId(weixinConfig.getAppid());
        ac.setAppSecret(weixinConfig.getSecret());
        /**
         * 是否对消息进行加密，对应于微信平台的消息加解密方式： 1：true进行加密且必须配置 encodingAesKey
         * 2：false采用明文模式，同时也支持混合模式
         */
        ac.setEncryptMessage(_Config.p.getBoolean("encryptMessage", false));
        ac.setEncodingAesKey(_Config.p.get("encodingAesKey", "setting it in config file"));
        return ac;
    }
    private static String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }
    private static String create_nonce_str() {
        return UUID.randomUUID().toString();
    }
}
